from flask import current_app, jsonify
from flask import g
from flask import render_template
from flask import request
from flask import session

from info import db
from info.models import News, User, Comment, CommentLike
from info.utils.commons import user_login_data
from info.utils.response_code import RET
from . import newsblue


@newsblue.route('/comment_like', methods=['POST'])
@user_login_data
def comment_like():
    # 1.判断用户是否登录
    if not g.user:
        return jsonify(errno=RET.LOGINERR,errmsg='用户未登录')
    # 2.获取参数，参数为空校验
    comment_id = request.json.get('comment_id')
    action = request.json.get('action')
    if not all([comment_id,action]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数不全')

    # 3.对操作类型进行校验
    if action not in ['add', 'remove']:
        return jsonify(errno=RET.PARAMERR,errmsg='命令有误')

    # 4.根据评论编号，查询评论对象是否存在
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='取出评论对象失败')
    if not comment: return jsonify(errno=RET.NODATA,errmsg='评论不存在')

    # 5.根据操作类型，进行点赞或者取消点赞
    if action == 'add':
        add_like = CommentLike()
        add_like.comment_id = comment_id
        add_like.user_id = g.user.id
        db.session.add(add_like)
        comment.like_count += 1
        db.session.commit()
    else:
        try:
            comment_love = CommentLike.query.filter(CommentLike.comment_id == comment_id).first()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR,errmsg="查询点赞对象失败")
        db.session.delete(comment_love)
        if comment.like_count > 0:
            comment.like_count -= 1
        db.session.commit()

    return jsonify(errno=RET.OK,errmsg='操作成功')


@newsblue.route('/news_comment', methods=['POST'])
@user_login_data
def news_comment():
    # 1.判断用户是否登录
    if not g.user:
        return jsonify(errno=RET.LOGINERR,errmsg='用户未登录')

    # 2.获取参数
    news_id = request.json.get("news_id")
    comment = request.json.get("comment")
    parent_id = request.json.get('parent_id')

    # 3.参数的为空校验
    if not all([news_id,comment]):
        return jsonify(errno=RET.NODATA,errmsg='参数不全')

    # 4.根据新闻编号取出新闻对象，判断新闻对象是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取新闻对象失败')

    # 5.创建评论对象,并为属性赋值
    comments = Comment()
    comments.user_id = g.user.id
    comments.news_id = news_id
    comments.content = comment
    if parent_id:
        comments.parent_id = parent_id

    db.session.add(comments)
    db.session.commit()
    return jsonify(errno=RET.OK,errmsg='评论成功',data=comments.to_dict())


@newsblue.route('/news_collect', methods=['POST'])
@user_login_data
def news_collect():
    # 1.获取参数
    news_id = request.json.get("news_id")
    action = request.json.get('action')

    # 2.判断用户登录
    if not g.user:
        return jsonify(errno=RET.NODATA,errmsg='用户未登录')

    # 3.参数校验
    if not all([news_id,action]):
        return jsonify(errno=RET.NODATA,errmsg='参数不全')

    # 4.校验请求操作是否合法
    if not action in ["collect", "cancel_collect"]:
        return  jsonify(errno=RET.PARAMERR,errmsg='请求方式有误')

    # 4.1 判断新闻对象是否存在
    news = None
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取新闻失败')

    # 5. 如果是action，5.1 先取出新闻对象
    if action == "collect":
        # 5.2 判断用户是否收藏过该新闻了
        if news in g.user.collection_news:
            return jsonify(error=RET.PARAMERR,errmsg='不可重复收藏')

        # 5.3 将新闻对象添加到用户收藏属性
        g.user.collection_news.append(news)
        return jsonify(errno=RET.OK,errmsg='收藏成功')

    # 6.如果是cancel_action，取消收藏
    elif action == 'cancel_collect':
        # 6.1判断用户是否未收藏此新闻
        if news not in g.user.collection_news:
            return jsonify(errno=RET.PARAMERR,errmsg='用户没有收藏该新闻')

        # 6.1将该新闻从用户收藏属性中删除
        g.user.collection_news.remove(news)
        return jsonify(errno=RET.OK,errmsg='取消收藏成功')


@newsblue.route('/<int:news_id>')
def detail(news_id):
    try:
        news = News.query.filter(News.id == news_id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取新闻对象失败")

    user = None
    user_id = session.get("user_id")
    try:
        user = User.query.get(user_id)
    except Exception as e:
        current_app.logger.error(e)

    # 查询热门新闻并携带数据
    hot_news = News.query.order_by(News.clicks.desc()).limit(6).all()
    news_list = []
    for item in hot_news:
        news_list.append(item.to_dict())

    # 查询用户收藏的所有新闻
    is_collected = False
    if user:
        if news in user.collection_news:
            is_collected = True

    # 查询用户评论内容，并携带至模板渲染
    try:
        comments = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取评论对象失败')

    # 查询用户点赞内容，并判断是否点赞
    ###############################################################
    comments_list = []
    commentLike_coment_ids = []
    if user:
        try:
            # 先取到所有点赞对象
            commentLike_list = CommentLike.query.filter(CommentLike.user_id == user.id).all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg='或许点赞对象失败')

        # 根据点赞对象获取该用户点赞的所有评论对象的id
        for commentLike in commentLike_list:
            commentLike_coment_ids.append(commentLike.comment_id)

    # 将是否点赞添加进comment.to_dict()的字典中，方便后端做点赞校验
    for comment in comments:
        is_liked = False
        if user and comment.id in commentLike_coment_ids:
            is_liked = True

        comments_dict = comment.to_dict()

        comments_dict["is_liked"] = is_liked

        comments_list.append(comments_dict)
    ######################################################################

    data = {
        "news": news,
        "user_info": user.to_dict() if user else '',
        "is_collected": is_collected,
        "news_list": news_list,
        "comments_list": comments_list
    }
    return render_template("news/detail.html",data=data)